home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i065: The VN news reader, Part02/03
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: rtech!rtech!bobm (Bob Mcqueer)
- Mod.sources: Volume 8, Issue 65
- Archive-name: vn/Part02
-
- [ I forgot to point out that I repacked the archives because of a patch
- Bob sent me. --r$ ]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If all goes well, you will see the message "End of archive 2 (of 3)."
- # Contents: reader.c strtok.c term_set.c tty.h tty_set.c tune.h
- # userlist.c vn.h vnglob.c
- # Wrapped by rs@mirror on Tue Feb 17 12:10:31 1987
- PATH=/bin:/usr/bin:/usr/ucb; export PATH
- echo shar: extracting "'reader.c'" '(18610 characters)'
- if test -f 'reader.c' ; then
- echo shar: will not over-write existing file "'reader.c'"
- else
- sed 's/^X//' >reader.c <<'@//E*O*F reader.c//'
- X/*
- X** vn news reader.
- X**
- X** reader.c - article reading interface - "more" like.
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "tty.h"
- X#include "config.h"
- X#include "vn.h"
- X#include "head.h"
- X#include "reader.h"
- X
- X#define PERTAB 8 /* tab expansion factor */
- X#define BACKTRACK 24
- X
- Xextern char *Printer,*Editor,*Mailer,*Poster,*Orgdir,*Savefile,*Savedir,*Ccfile;
- Xextern int L_allow;
- Xextern int C_allow;
- Xextern int Rot;
- Xextern int Headflag;
- Xextern int Digest;
- Xextern char *No_msg;
- Xextern char *Roton_msg;
- Xextern char *Rotoff_msg;
- Xextern char *Hdon_msg;
- Xextern char *Hdoff_msg;
- X
- Xextern char *T_head, *FT_head, *N_head, *L_head, *RT_head, *DIS_head;
- Xextern char *TO_head, *F_head, *P_head, *M_head, *R_head;
- X
- Xextern char Cxrtoi[], Cxitor[];
- X
- Xstatic FILE *Fpread;
- Xstatic char *Fname;
- Xstatic char *Lookahead;
- Xstatic int Rlines;
- Xstatic int Hlines;
- X
- X#ifdef ADDRMUNGE
- Xstatic int Newaddr;
- X#endif
- X
- X/*
- X readstr routine is the "funnel" to the reading state,
- X and controls signal setting. Some "session" context is passed
- X along to allow jumping back to a different display
- X
- X WARNING:
- X
- X NOTHING below readstr should call strtok()
- X*/
- X
- Xreadstr (s,crec,highrec,count)
- Xchar *s;
- Xint *crec, *highrec;
- Xint count;
- X{
- X char *fnext, *strtok();
- X int pc;
- X Fname = strtok(s,LIST_SEP);
- X if (Fname != NULL)
- X {
- X term_set (ERASE);
- X sig_set (BRK_READ,&Fpread);
- X fnext = strtok(NULL,LIST_SEP);
- X while (Fname != NULL && readfile(fnext,&pc) >= 0)
- X {
- X if (Digest)
- X unlink (Fname);
- X Fname = fnext;
- X fnext = strtok (NULL,LIST_SEP);
- X }
- X if (Digest && Fname != NULL)
- X unlink (Fname);
- X if (pc != 0)
- X forward (pc, crec, highrec);
- X else
- X {
- X *crec += count;
- X if (*crec >= *highrec)
- X *crec = *highrec - 1;
- X }
- X sig_set (BRK_RFIN);
- X show ();
- X term_set (MOVE, 0, *crec);
- X }
- X else
- X {
- X preinfo ("%s",No_msg);
- X term_set (MOVE, 0, *crec);
- X }
- X}
- X
- X/*
- X readfile presents article:
- X sn - name of next article, NULL if last.
- X pages - pages to advance on return, if applicable
- X returns 0 for "continue", <0 for "quit"
- X*/
- Xstatic readfile (sn,pages)
- Xchar *sn;
- Xint *pages;
- X{
- X FILE *fopen();
- X int lines,percent,artlin;
- X long rew_pos, ftell();
- X char c, buf[RECLEN], mid[RECLEN], ngrp[RECLEN], dist[RECLEN];
- X char from[RECLEN], title[RECLEN], flto[RECLEN], reply[RECLEN];
- X char pstr[24], dgname[48], getpgch(), *index(), *digest_extract();
- X char *tgetstr();
- X
- X *pages = 0;
- X
- X term_set(ERASE);
- X
- X if (Digest)
- X {
- X lines = atoi(Fname);
- X if ((Fname = digest_extract(dgname,lines)) == NULL)
- X {
- X printf ("couldn't extract article %d",lines);
- X return (0);
- X }
- X }
- X
- X if ((Fpread = fopen(Fname,"r")) == NULL)
- X {
- X printf ("couldn't open article %s",Fname);
- X return (0);
- X }
- X
- X Hlines = gethead (mid, from, title, ngrp, flto, reply, dist, &artlin);
- X printf (ANFORM,Fname,Cxrtoi[PG_HELP]);
- X lines = 1;
- X rew_pos = ftell(Fpread);
- X if (Headflag)
- X {
- X rewind(Fpread);
- X Rlines = 0;
- X }
- X else
- X {
- X /* use do_out to guard against control sequences */
- X Rlines = Hlines;
- X sprintf (buf,"%s%s\n",T_head,title);
- X lines += do_out(buf,1);
- X sprintf (buf,"%s%s\n",F_head,from);
- X lines += do_out(buf,1);
- X if (index(ngrp,',') != NULL)
- X {
- X sprintf (buf,"%s%s\n",N_head,ngrp);
- X lines += do_out(buf,1);
- X }
- X if (*flto != '\0')
- X {
- X sprintf (buf,"%s%s\n",FT_head,flto);
- X lines += do_out(buf,1);
- X }
- X printf ("%s%d\n",L_head,artlin); /* no controls */
- X ++lines;
- X }
- X
- X /* will return out of outer while loop */
- X Lookahead = NULL;
- X while (1)
- X {
- X /*
- X ** lines counts folded lines from do_out.
- X ** globals Hlines and Rlines refer to records.
- X ** If Lookahead is null after this loop, we've
- X ** hit EOF.
- X */
- X lines += do_out(Lookahead,L_allow-lines);
- X while (1)
- X {
- X if (Lookahead == NULL)
- X {
- X if (fgets(buf,RECLEN-1,Fpread) == NULL)
- X break;
- X Lookahead = buf;
- X if (Rot != 0 && Rlines >= Hlines)
- X rot_line(buf);
- X ++Rlines;
- X }
- X if (lines >= L_allow)
- X break;
- X lines += do_out(buf,L_allow-lines);
- X }
- X
- X if (Lookahead != NULL)
- X {
- X /*
- X ** calculation is truncated rather than rounded,
- X ** so we shouldn't get "100%". Subtract 2 for
- X ** 1 line lookahead and empty line at beginning
- X ** of article.
- X */
- X if (Headflag)
- X percent = ((Rlines-2)*100)/(artlin+Hlines);
- X else
- X percent = ((Rlines-Hlines-2)*100)/artlin;
- X sprintf (pstr,PAGE_MID,percent);
- X }
- X else
- X {
- X if (sn == NULL)
- X strcpy (pstr,PAGE_END);
- X else
- X strcpy (pstr,PAGE_NEXT);
- X }
- X c = getpgch(pstr,mid,from,reply,title,ngrp,flto,dist);
- X
- X /*
- X handle user input:
- X CAUTION!! return cases must close Fpread.
- X */
- X switch (c)
- X {
- X case PG_NEXT:
- X fclose (Fpread);
- X return (0);
- X case PG_FLIP:
- X *pages = 1; /* fall through */
- X case PG_QUIT:
- X fclose (Fpread);
- X return (-1);
- X case PG_REWIND:
- X if (Headflag)
- X {
- X Rlines = 0;
- X rewind (Fpread);
- X }
- X else
- X {
- X fseek (Fpread,rew_pos,0);
- X Rlines = Hlines;
- X }
- X Lookahead = NULL;
- X lines = 2 - RECBIAS;
- X break;
- X case PG_SEARCH:
- X searcher(buf);
- X lines = 2 - RECBIAS;
- X lines += do_out(buf,L_allow-lines);
- X break;
- X case PG_WIND:
- X fseek (Fpread,0L,2);
- X lines = 2 - RECBIAS;
- X Lookahead = NULL;
- X break;
- X case PG_STEP:
- X if (Lookahead == NULL)
- X {
- X fclose (Fpread);
- X return (0);
- X }
- X lines = L_allow - 1;
- X break;
- X default:
- X if (Lookahead == NULL)
- X {
- X fclose (Fpread);
- X return (0);
- X }
- X lines = 2 - RECBIAS;
- X break;
- X }
- X }
- X}
- X
- X/*
- X gethead obtains subject, reply, message id, from, lines, newsgroup and
- X followup-to lines of article for later use in mailing replies and
- X posting followups, does not rewind, but leaves file at end of header
- X lines. Returns number of header lines.
- X*/
- Xstatic gethead (mid, from, title, ngrp, flto, reply, dist, lin)
- Xchar *mid, *from, *title, *ngrp, *flto, *reply, *dist;
- Xint *lin;
- X{
- X int count;
- X char buf [RECLEN], *index();
- X long pos,ftell();
- X
- X#ifdef ADDRMUNGE
- X Newaddr = 1;
- X#endif
- X
- X *lin = 0;
- X *dist = *mid = *from = *title = *ngrp = *flto = *reply = '\0';
- X
- X /* for conditional is abnormal - expected exit is break */
- X for (count = 0; count < HDR_LINES && fgets(buf,RECLEN-1,Fpread) != NULL; ++count)
- X {
- X
- X /* reset position and bail out at first non-header line */
- X if (index(buf,':') == NULL)
- X {
- X pos = ftell(Fpread);
- X pos -= strlen(buf);
- X fseek (Fpread,pos,0);
- X break;
- X }
- X
- X#ifdef MAILSMART
- X if (strncmp(buf,RT_head,RTHDLEN) == 0)
- X {
- X buf [strlen(buf)-1] = '\0';
- X strcpy (reply,buf+RTHDLEN);
- X continue;
- X }
- X#else
- X if (strncmp(buf,P_head,PHDLEN) == 0)
- X {
- X buf [strlen(buf)-1] = '\0';
- X strcpy (reply,buf+PHDLEN);
- X continue;
- X }
- X#endif
- X if (strncmp(buf,DIS_head,DISHDLEN) == 0)
- X {
- X buf [strlen(buf)-1] = '\0';
- X strcpy (dist,buf+DISHDLEN);
- X continue;
- X }
- X if (strncmp(buf,M_head,MHDLEN) == 0)
- X {
- X buf [strlen(buf)-1] = '\0';
- X strcpy (mid,buf+MHDLEN);
- X continue;
- X }
- X if (strncmp(buf,F_head,FHDLEN) == 0)
- X {
- X buf [strlen(buf)-1] = '\0';
- X strcpy (from,buf+FHDLEN);
- X continue;
- X }
- X if (strncmp(buf,T_head,THDLEN) == 0)
- X {
- X buf [strlen(buf)-1] = '\0';
- X strcpy (title,buf+THDLEN);
- X continue;
- X }
- X if (strncmp(buf,N_head,NHDLEN) == 0)
- X {
- X buf [strlen(buf)-1] = '\0';
- X strcpy (ngrp,buf+NHDLEN);
- X continue;
- X }
- X if (strncmp(buf,FT_head,FTHDLEN) == 0)
- X {
- X buf [strlen(buf)-1] = '\0';
- X strcpy (flto,buf+FTHDLEN);
- X continue;
- X }
- X if (strncmp(buf,L_head,LHDLEN) == 0)
- X {
- X buf [strlen(buf)-1] = '\0';
- X *lin = atoi(buf+LHDLEN);
- X continue;
- X }
- X }
- X#ifdef MAILSMART
- X if (*reply == '\0')
- X strcpy(reply,from);
- X#endif
- X return (count);
- X}
- X
- X/*
- X getpgch prints prompt and gets command from user
- X handles "mail", "save" and "followup" internally
- X as well as flag resets.
- X*/
- Xstatic char getpgch(prompt,mid,from,reply,title,ngrp,flto,dist)
- Xchar *prompt, *mid, *from, *reply, *title, *ngrp, *flto, *dist;
- X{
- X char c;
- X int ic;
- X term_set (ONREVERSE);
- X printf("%s\015",prompt);
- X term_set (OFFREVERSE);
- X while ((ic=getnoctl()) != EOF)
- X {
- X switch (c = Cxitor[ic])
- X {
- X case SETROT:
- X term_set (ZAP,0,PPR_MAX);
- X if (Rot == 0)
- X {
- X Rot = 13;
- X printf ("%s\n",Roton_msg);
- X }
- X else
- X {
- X Rot = 0;
- X printf ("%s\n",Rotoff_msg);
- X }
- X if (Lookahead != NULL && Rlines > Hlines)
- X rot_line(Lookahead);
- X break;
- X case HEADTOG:
- X term_set (ZAP,0,PPR_MAX);
- X if (Headflag)
- X {
- X Headflag = FALSE;
- X printf ("%s\n",Hdoff_msg);
- X }
- X else
- X {
- X Headflag = TRUE;
- X printf ("%s\n",Hdon_msg);
- X }
- X break;
- X case PG_HELP:
- X term_set (ZAP,0,PPR_MAX);
- X help_pg ();
- X break;
- X case PG_REPLY:
- X mail (reply,title,from);
- X break;
- X case PG_FOLLOW:
- X followup (mid,title,ngrp,flto,from,dist);
- X break;
- X case SAVE:
- X saver ();
- X break;
- X case PRINT:
- X printr ();
- X break;
- X default:
- X term_set (ZAP,0,PPR_MAX);
- X return (c);
- X }
- X
- X term_set (ONREVERSE);
- X printf("%s\015",prompt);
- X term_set (OFFREVERSE);
- X }
- X term_set (ZAP,0,PPR_MAX);
- X return (c);
- X}
- X
- X/*
- X save article
- X Like the savestr routine, it "loses" some storage every time
- X the user specifies a new file, but this should not be significant
- X*/
- Xstatic saver ()
- X{
- X char *fn,cmd[RECLEN],*str_store(),*rprompt();
- X
- X tty_set (SAVEMODE);
- X sprintf (cmd,SAVFORM,Savefile);
- X fn = rprompt(cmd,cmd);
- X if (fn != NULL)
- X Savefile = str_store(fn);
- X if (*Savefile != '/' && *Savefile != '$')
- X sprintf (cmd,"cat %s >>%s/%s",Fname,Savedir,Savefile);
- X else
- X sprintf (cmd,"cat %s >>%s",Fname,Savefile);
- X system (cmd);
- X tty_set (RESTORE);
- X}
- X
- X/*
- X invoke editor on new temp file, mail using reply line,
- X possibly first allowing user to overide the reply (not INLETTER)
- X*/
- Xstatic mail (p, t, f)
- Xchar *p, *t, *f;
- X{
- X char *new, fn[L_tmpnam], cmd [RECLEN+60], *rprompt ();
- X FILE *fp, *fopen();
- X
- X tmpnam (fn);
- X if ((fp = fopen(fn,"w")) == NULL)
- X printex ("can't open %s\n",fn);
- X
- X if ((new = index(p, '(')) != NULL)
- X *new = '\0'; /* a poor way of deleting comments */
- X
- X#ifdef ADDRMUNGE
- X if (Newaddr)
- X {
- X Newaddr = 0;
- X ADDRMUNGE(p);
- X }
- X#endif
- X
- X if (strncmp(t, FPFIX, FPFLEN) == 0)
- X t += FPFLEN; /* don't add multiple Re:s */
- X#ifdef INLETTER
- X fprintf (fp,"%s%s\n%s%s%s\n\n%s:\n", TO_head, p, T_head, FPFIX, t, f);
- X#else
- X fprintf (fp,"%s%s%s\n\n%s:\n", T_head, FPFIX, t, f);
- X#endif
- X
- X edcopy (fp);
- X fclose (fp);
- X tty_set (SAVEMODE);
- X
- X#ifndef INLETTER
- X sprintf (cmd,"ADDRESS: %s\nreturn to accept, or input new address: ",p);
- X if ((new = rprompt(cmd,cmd)) != NULL)
- X strcpy (p,new);
- X#endif
- X
- X sprintf (cmd,"%s %s", Editor, fn);
- X chdir (Orgdir);
- X system (cmd);
- X cd_group ();
- X new = rprompt ("still want to mail it ? ",cmd);
- X if (new != NULL && (*new == 'y' || *new == 'Y'))
- X {
- X#ifndef INLETTER
- X sprintf (cmd,"%s '%s' <%s", Mailer, p, fn);
- X#else
- X sprintf (cmd,"%s <%s", Mailer, fn);
- X#endif
- X system (cmd);
- X printf ("given to mailer\n");
- X }
- X else
- X printf ("not mailed\n");
- X unlink (fn);
- X tty_set (RESTORE);
- X term_set (RESTART);
- X}
- X
- X/*
- X post a followup article, invoking editor for user after creating
- X new temp file. remove after posting. Hack in ".followup" if posting
- X newsgroup ends in ".general" - similar hack for preventing mod &
- X announce groups - should really be more thorough and parse the
- X whole string. User can change, anyway.
- X*/
- Xstatic followup (m,t,n,ft,oa,dist)
- Xchar *m, *t, *n, *ft, *oa, *dist;
- X{
- X char fn[L_tmpnam], *new, cmd [RECLEN], *rprompt();
- X FILE *f, *fopen();
- X char *rindex();
- X
- X if (*ft != '\0')
- X strcpy (cmd,ft);
- X else
- X strcpy (cmd,n);
- X new = rindex(cmd,'.');
- X if (new != NULL && strcmp(new,".general") == 0)
- X strcpy (new,".followup");
- X if ( strncmp(cmd, "mod.", 4) == 0 || strcmp(new, ".announce") == 0)
- X {
- X term_set (ONREVERSE);
- X printf("Cannot post a follow-up to \"%s\", reply with mail to moderator\007\n",
- X cmd);
- X term_set (OFFREVERSE);
- X return;
- X }
- X
- X tmpnam (fn);
- X if ((f = fopen(fn,"w")) == NULL)
- X printex ("can't open %s\n",fn);
- X
- X if (strncmp(t, FPFIX, FPFLEN) == 0)
- X t += FPFLEN; /* don't add multiple Re:s */
- X fprintf (f,"%s%s%s\n%s%s\n%s%s\n",T_head,FPFIX,t,N_head,cmd,R_head,m);
- X if (*dist != '\0')
- X fprintf(f,"%s%s\n",DIS_head,dist);
- X fprintf (f,"\nin article %s, %s says:\n",m,oa);
- X edcopy (f);
- X fclose (f);
- X tty_set (SAVEMODE);
- X sprintf (cmd,"%s %s", Editor, fn);
- X chdir (Orgdir);
- X system (cmd);
- X cd_group ();
- X new = rprompt("still want to post it ? ",cmd);
- X if (new != NULL && (*new == 'y' || *new == 'Y'))
- X {
- X sprintf (cmd,"%s <%s", Poster, fn);
- X system (cmd);
- X printf ("given to posting program\n");
- X save_article (fn);
- X }
- X else
- X printf ("not posted\n");
- X unlink (fn);
- X tty_set (RESTORE);
- X term_set (RESTART);
- X}
- X
- X/*
- X get user buffer, return whitespace delimited token
- X without using strtok(). buffer is allowed to overwrite
- X prompt string.
- X*/
- Xstatic char *
- Xrprompt(s,buf)
- Xchar *s,*buf;
- X{
- X printf("%s",s);
- X fgets (buf,RECLEN-1,stdin);
- X while (*buf == ' ' || *buf == '\t')
- X ++buf;
- X if (*buf == '\n' || *buf == '\0')
- X return (NULL);
- X for (s = buf; *s != ' ' && *s != '\t' && *s != '\n' && *s != '\0'; ++s)
- X ;
- X *s = '\0';
- X return (buf);
- X}
- X
- X/*
- X edcopy copies article to file which user is editting for
- X a reply or followup, so it may be referenced. It places
- X ED_MARK in the left hand margin.
- X*/
- Xedcopy(fp)
- XFILE *fp;
- X{
- X long current;
- X char buf[RECLEN];
- X int i;
- X
- X /* save position, rewind and skip over header lines */
- X current = ftell(Fpread);
- X rewind (Fpread);
- X for (i=0; i < HDR_LINES; ++i)
- X {
- X if (fgets(buf,RECLEN-1,Fpread) == NULL)
- X break;
- X if (strncmp(buf,L_head,LHDLEN) == 0)
- X break;
- X }
- X
- X /* if line already begins with ED_MARK, forget about the space */
- X while (fgets(buf,RECLEN-1,Fpread) != NULL)
- X {
- X if (buf[0] == ED_MARK)
- X fprintf(fp,"%c%s",ED_MARK,buf);
- X else
- X fprintf(fp,"%c %s",ED_MARK,buf);
- X }
- X
- X /* restore position */
- X fseek(Fpread,current,0);
- X}
- X
- X/*
- X help menus
- X*/
- Xstatic help_pg()
- X{
- X h_print (Cxrtoi[PG_NEXT],HPG_NEXT);
- X h_print (Cxrtoi[PG_QUIT],HPG_QUIT);
- X h_print (Cxrtoi[PG_FLIP],HPG_FLIP);
- X h_print (Cxrtoi[PG_REWIND],HPG_REWIND);
- X h_print (Cxrtoi[PG_WIND],HPG_WIND);
- X h_print (Cxrtoi[PG_SEARCH],HPG_SEARCH);
- X h_print (Cxrtoi[PG_STEP],HPG_STEP);
- X h_print (Cxrtoi[PG_REPLY],HPG_REPLY);
- X h_print (Cxrtoi[PG_FOLLOW],HPG_FOLLOW);
- X h_print (Cxrtoi[SAVE],HPG_SAVE);
- X h_print (Cxrtoi[PRINT],HPG_PRINT);
- X h_print (Cxrtoi[SETROT],HPG_ROT);
- X h_print (Cxrtoi[HEADTOG],HPG_HEAD);
- X h_print (Cxrtoi[PG_HELP],HPG_HELP);
- X printf ("%s\n",HPG_DEF);
- X}
- X
- Xrot_line (s)
- Xunsigned char *s;
- X{
- X for ( ; *s != '\0'; ++s)
- X {
- X if (*s >= 'A' && *s <= 'Z')
- X {
- X *s += Rot;
- X if (*s > 'Z')
- X *s -= 26;
- X continue;
- X }
- X if (*s >= 'a' && *s <= 'z')
- X {
- X *s += Rot;
- X if (*s > 'z')
- X *s -= 26;
- X }
- X }
- X}
- X
- X/*
- X** output record. folds record to terminal width on word boundaries,
- X** returning number of lines output. If limit is reached, remainder
- X** of buffer waiting to be output is returned. Processes several
- X** special characters:
- X** form-feed - return "lim" lines so we stop on that line
- X** tabs - counts "expanded" width
- X** backspace - assumes they work, -1 width unless in first col.
- X** bell - pass through with zero width
- X** newline - end of record.
- X** del - turns into '_'
- X** other control - 'A' - 1 added ('01' = ctl-A). Makes escape = "[".
- X** (prevents "letter bombs" containing inappropriate control
- X** sequences for the terminal).
- X**
- X** Sets Lookahead pointer to remainder of line or NULL.
- X*/
- Xstatic do_out(s,lim)
- Xchar *s;
- Xint lim;
- X{
- X int len,i;
- X char cs,*word,*start;
- X
- X Lookahead = NULL;
- X if (s == NULL)
- X return(0);
- X len = 0;
- X start = word = s;
- X
- X /*
- X ** NOTE: "normal" return is buried inside switch, at newline
- X ** ending record
- X */
- X for (i=0; i < lim; ++i)
- X {
- X for ( ; len < C_allow; ++s)
- X {
- X switch (*s)
- X {
- X case '\n':
- X *s = '\0'; /* fall through */
- X case '\0':
- X printf("%s\n",start);
- X return(i+1);
- X case '\t':
- X len = ((len/PERTAB)+1)*PERTAB;
- X word = s;
- X break;
- X case '\b':
- X if (len > 0)
- X --len;
- X break;
- X case '\014':
- X *s = ' ';
- X i = lim-1; /* fall through */
- X case ' ':
- X word = s+1;
- X ++len;
- X break;
- X case '\177':
- X *s = '_';
- X ++len;
- X break;
- X default:
- X if (*s < ' ')
- X *s += 'A' - 1;
- X ++len; /* fall through */
- X case '\07':
- X break;
- X }
- X }
- X cs = *s;
- X *s = '\0';
- X if ((len = strlen(word)) < BACKTRACK)
- X {
- X *s = cs;
- X s = word;
- X cs = *s;
- X *s = '\0';
- X }
- X else
- X len = 0;
- X printf("%s\n",start);
- X start = s;
- X *s = cs;
- X }
- X Lookahead = start;
- X return(lim);
- X}
- X
- Xsave_article(tempfname)
- Xchar *tempfname;
- X{
- X FILE *in, *out;
- X int c;
- X time_t timenow, time();
- X char *today, *ctime();
- X
- X
- X if ((in = fopen(tempfname, "r")) == NULL)
- X return;
- X if ((out = fopen(Ccfile, "a")) == NULL)
- X {
- X fclose(in);
- X return;
- X }
- X timenow = time((time_t)0);
- X today = ctime(&timenow);
- X fprintf(out,"From vn %s",today);
- X while ((c=getc(in)) != EOF)
- X putc(c, out);
- X putc('\n', out);
- X fclose(in);
- X fclose(out);
- X printf ("a copy has been saved in %s\n", Ccfile);
- X}
- X
- X/*
- X send article to printer
- X*/
- Xstatic printr ()
- X{
- X char cmd[RECLEN];
- X
- X tty_set (SAVEMODE);
- X printf("Sent to printer\n");
- X sprintf (cmd,"%s %s 2>/dev/null",Printer,Fname);
- X system (cmd);
- X tty_set (RESTORE);
- X}
- X
- X/*
- X search article for specified search pattern, returning the line on which
- X it is found in buf, a null buffer otherwise. The input file will
- X be positioned either after the line on which the pattern is
- X found, or unaaltered if match fails.
- X*/
- Xsearcher (buf)
- Xchar *buf;
- X{
- X static char searchstr[RECLEN] = "";
- X char lasave[RECLEN];
- X char *s, *reg, *rprompt(), *regcmp(), *regex();
- X long current;
- X int orlines;
- X
- X /* save position, then request search pattern */
- X current = ftell(Fpread);
- X orlines = Rlines;
- X
- X tty_set (SAVEMODE);
- X sprintf (lasave,SEARCHFORM,searchstr);
- X s = rprompt(lasave,lasave);
- X tty_set (RESTORE);
- X if (s != NULL)
- X strcpy(searchstr, lasave);
- X
- X /* Now compile the search string */
- X if(( reg = regcmp(searchstr, (char *)0)) == NULL) {
- X printf("Invalid search string \"%s\"\n", searchstr);
- X *buf = '\0';
- X return;
- X }
- X
- X /* try lookahead buffer first */
- X if (Lookahead != NULL && regex(reg,Lookahead) != NULL)
- X {
- X strcpy(buf,Lookahead);
- X regfree(reg);
- X return;
- X }
- X
- X /* Lookahead can point into buf */
- X if (Lookahead != NULL)
- X strcpy(lasave,Lookahead);
- X
- X /* now start reading lines, rotating if necessary and do search */
- X while (fgets(buf,RECLEN-1,Fpread) != NULL)
- X {
- X if (Rot != 0 && Rlines >= Hlines)
- X rot_line(buf);
- X ++Rlines;
- X if( regex(reg, buf) != NULL ){ /* Got it */
- X term_set (ONREVERSE);
- X printf("\n\tSkipping ....\n\n");
- X term_set (OFFREVERSE);
- X regfree(reg);
- X return;
- X }
- X }
- X
- X /* no dice, so restore position */
- X regfree(reg);
- X term_set (ONREVERSE);
- X printf("Cannot find string \"%s\" in remainder of article\007\n",
- X searchstr);
- X term_set (OFFREVERSE);
- X fseek(Fpread,current,0);
- X Rlines = orlines;
- X if (Lookahead != NULL)
- X strcpy(buf,lasave);
- X else
- X *buf = '\0';
- X return(0.0);
- X}
- @//E*O*F reader.c//
- if test 18610 -ne "`wc -c <'reader.c'`"; then
- echo shar: error transmitting "'reader.c'" '(should have been 18610 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'strtok.c'" '(1082 characters)'
- if test -f 'strtok.c' ; then
- echo shar: will not over-write existing file "'strtok.c'"
- else
- sed 's/^X//' >strtok.c <<'@//E*O*F strtok.c//'
- X/*
- X** vn news reader.
- X**
- X** strtok.c - strtok() and strpbrk() string routines using UCB index().
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X
- Xchar *strpbrk (s,del)
- Xchar *s, *del;
- X{
- X char *ptr,*index();
- X if (s == NULL)
- X return (NULL);
- X for (; *del != '\0'; ++del)
- X if ((ptr = index(s,*del)) != NULL)
- X return (ptr);
- X return (NULL);
- X}
- X
- Xchar *strtok(str,delim)
- Xchar *str, *delim;
- X{
- X char *tokstart, *tokend, *first_ch (), *last_ch();
- X static char *save=NULL;
- X
- X if (str != NULL)
- X save = str;
- X
- X if (save == NULL)
- X return (NULL);
- X
- X tokstart = first_ch (save, delim);
- X tokend = last_ch (tokstart, delim);
- X save = first_ch (tokend, delim);
- X *tokend = '\0';
- X
- X if (*tokstart == '\0')
- X return (NULL);
- X
- X return (tokstart);
- X}
- X
- Xstatic char *first_ch (str,delim)
- Xchar *str,*delim;
- X{
- X char *index ();
- X char *f;
- X
- X for (f = str; *f != '\0' && index(delim,*f) != NULL; ++f)
- X ;
- X
- X return (f);
- X}
- X
- Xstatic char *last_ch (str,delim)
- Xchar *str,*delim;
- X{
- X char *index ();
- X char *f;
- X
- X for (f = str; *f != '\0' && index(delim,*f) == NULL; ++f)
- X ;
- X
- X return (f);
- X}
- @//E*O*F strtok.c//
- if test 1082 -ne "`wc -c <'strtok.c'`"; then
- echo shar: error transmitting "'strtok.c'" '(should have been 1082 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'term_set.c'" '(4914 characters)'
- if test -f 'term_set.c' ; then
- echo shar: will not over-write existing file "'term_set.c'"
- else
- sed 's/^X//' >term_set.c <<'@//E*O*F term_set.c//'
- X/*
- X** vn news reader.
- X**
- X** term_set.c - terminal control, hides termcap interface
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include "tty.h"
- X#include "vn.h"
- X
- Xextern int L_allow, C_allow;
- Xextern char *Ku, *Kd, *Kl, *Kr;
- X
- Xstatic outc (c)
- Xchar c;
- X{
- X putchar (c);
- X}
- X
- X/*
- X term_set controls terminal through termcap
- X START sets global parameters related to terminal also,
- X as well as allocating display buffer which depends on
- X terminal lines, and allocating escape strings. RESTART
- X simply re-issues the initialization - used following system
- X calls that could have goofed up the terminal state.
- X*/
- X
- X/*
- X** Escape strings.
- X*/
- X
- Xstatic char *Cm,*Cl,*So,*Se,*Te,*Bc,*Ce,*Ti,*Ks,*Ke;
- X#ifdef USEVS
- Xstatic char *Vs,*Ve;
- X#endif
- X
- Xstatic int Backspace; /* backspace works */
- Xstatic int Overstrike; /* terminal overstrikes */
- X
- Xstatic t_setup()
- X{
- X int i;
- X char *tgetstr(), *getenv(), *str_store();
- X char *c, tc_buf[2048],optstr[2048];
- X
- X c = optstr;
- X if (tgetent(tc_buf,getenv("TERM")) != 1)
- X printex ("%s - unknown terminal",getenv("TERM"));
- X
- X /* get needed capabilities */
- X Cm = str_store(tgetstr("cm",&c));
- X Cl = str_store(tgetstr("cl",&c));
- X So = str_store(tgetstr("so",&c));
- X Se = str_store(tgetstr("se",&c));
- X Te = str_store(tgetstr("te",&c));
- X Ti = str_store(tgetstr("ti",&c));
- X Bc = str_store(tgetstr("bc",&c));
- X Ce = str_store(tgetstr("ce",&c));
- X Kd = str_store(tgetstr("kd",&c));
- X Ke = str_store(tgetstr("ke",&c));
- X Kl = str_store(tgetstr("kl",&c));
- X Kr = str_store(tgetstr("kr",&c));
- X Ks = str_store(tgetstr("ks",&c));
- X Ku = str_store(tgetstr("ku",&c));
- X#ifdef USEVS
- X Vs = str_store(tgetstr("vs",&c));
- X Ve = str_store(tgetstr("ve",&c));
- X#endif
- X Backspace = tgetflag("bs");
- X Overstrike = tgetflag("os");
- X
- X if ( *Cm == '\0' || *Cl == '\0')
- X {
- X printex ("cursor control and erase capability needed");
- X }
- X
- X /*
- X ** Checks for arrow keys which don't issue something beginning
- X ** with <ESC>. This is more paranoid than we need to be, strictly
- X ** speaking - we could get away with any string which didn't
- X ** conflict with controls used for commands. However, that would
- X ** be a maintenance headache - we will simply reserve <ESC> as the
- X ** only char not to be used for commands, and punt on terminals
- X ** which don't send reasonable arrow keys. It would be confusing
- X ** to have keys work partially, also. I know of no terminal with
- X ** one arrow key beginning with an escape, and another beginning
- X ** with something else, but let's be safe. This also insists on
- X ** definitions for all 4 arrows, which seems reasonable.
- X */
- X
- X if ((*Ku != '\0' && *Ku != '\033') || *Kl != *Ku || *Kr != *Ku || *Kd != *Ku)
- X {
- X fgprintf("WARNING: arrow keys will not work for this terminal");
- X Ku = Kd = Kl = Kr = Kd = Ke = "";
- X }
- X
- X if (Overstrike)
- X fgprintf ("WARNING: terminal overstrikes - can't update display without erase\n");
- X
- X i = RECBIAS+1 < HHLINES+2 ? HHLINES+2 : RECBIAS+1;
- X if ((L_allow = tgetnum("li")) < i)
- X {
- X if (L_allow < 0)
- X printex ("can't determine number of lines on terminal");
- X printex ("too few lines for display - %d needed", i);
- X }
- X
- X /*
- X ** C_allow set so as to not use extreme right column.
- X ** Avoids "bad wraparound" problems - we're deciding it's best
- X ** to ALWAYS assume no automargin, and take care of it ourselves
- X */
- X if((C_allow = tgetnum("co")) > MAX_C)
- X C_allow = MAX_C;
- X else
- X --C_allow;
- X if (C_allow < MIN_C)
- X {
- X if (C_allow < 0)
- X printex("can't determine number of columns on terminal.");
- X printex ("too few columns for display - %d needed",MIN_C);
- X }
- X
- X L_allow -= RECBIAS;
- X page_alloc();
- X tputs(Ti,1,outc);
- X tputs(Ks,1,outc);
- X#ifdef USEVS
- X tputs(Vs,1,outc);
- X#endif
- X}
- X
- X/* VARARGS */
- Xterm_set(cmd,x,y)
- Xint cmd,x,y;
- X{
- X char *tgoto();
- X int i;
- X switch (cmd)
- X {
- X case MOVE:
- X tputs (tgoto(Cm,x,y),1,outc);
- X break;
- X case ERASE:
- X tputs(Cl,1,outc);
- X break;
- X case ONREVERSE:
- X tputs(So,1,outc);
- X break;
- X case OFFREVERSE:
- X tputs(Se,1,outc);
- X break;
- X case START:
- X t_setup();
- X break;
- X case RESTART:
- X tputs(Ti,1,outc);
- X tputs(Ks,1,outc);
- X#ifdef USEVS
- X tputs(Vs,1,outc);
- X#endif
- X break;
- X case STOP:
- X term_set (MOVE,0,L_allow+RECBIAS-1);
- X printf ("\n");
- X tputs(Ke,1,outc);
- X tputs(Te,1,outc);
- X#ifdef USEVS
- X tputs(Ve,1,outc);
- X#endif
- X break;
- X case RUBSEQ:
- X if (Overstrike)
- X {
- X /* space overprint is futile */
- X if (Backspace)
- X putchar('\010');
- X else
- X tputs(Bc,1,outc);
- X break;
- X }
- X if (Backspace)
- X printf("%c %c",'\010','\010');
- X else
- X {
- X tputs(Bc,1,outc);
- X putchar(' ');
- X tputs(Bc,1,outc);
- X }
- X break;
- X case ZAP:
- X if (Ce != NULL && *Ce != '\0')
- X tputs(Ce,1,outc);
- X else
- X {
- X if (Overstrike)
- X break; /* punt */
- X for (i=x; i < y; ++i)
- X putchar(' ');
- X if (Backspace)
- X {
- X for (i=x; i < y; ++i)
- X putchar('\010');
- X }
- X else
- X {
- X for (i=x; i < y; ++i)
- X tputs(Bc,1,outc);
- X }
- X }
- X break;
- X default:
- X printex ("term_set unknown code (%d)",cmd);
- X break;
- X }
- X return (0);
- X}
- @//E*O*F term_set.c//
- if test 4914 -ne "`wc -c <'term_set.c'`"; then
- echo shar: error transmitting "'term_set.c'" '(should have been 4914 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'tty.h'" '(404 characters)'
- if test -f 'tty.h' ; then
- echo shar: will not over-write existing file "'tty.h'"
- else
- sed 's/^X//' >tty.h <<'@//E*O*F tty.h//'
- X/*
- X** vn news reader.
- X**
- X** tty.h - codes for tty_set and term_set
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#define MOVE 100
- X#define ERASE 101
- X#define START 102
- X#define STOP 103
- X#define RUBSEQ 104
- X#define ZAP 105
- X#define ONREVERSE 106
- X#define OFFREVERSE 107
- X#define RESTART 108
- X
- X#define RAWMODE 200
- X#define COOKED 201
- X#define SAVEMODE 202
- X#define RESTORE 203
- X#define BACKSTOP 204
- @//E*O*F tty.h//
- if test 404 -ne "`wc -c <'tty.h'`"; then
- echo shar: error transmitting "'tty.h'" '(should have been 404 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'tty_set.c'" '(2552 characters)'
- if test -f 'tty_set.c' ; then
- echo shar: will not over-write existing file "'tty_set.c'"
- else
- sed 's/^X//' >tty_set.c <<'@//E*O*F tty_set.c//'
- X/*
- X** vn news reader.
- X**
- X** tty_set.c - interface to ioctl (system tty interface)
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#ifdef SYSV
- X#include <termio.h>
- X#else
- X#include <sgtty.h>
- X#endif
- X
- X#include "tty.h"
- X
- Xextern char Erasekey,Killkey;
- X
- X#ifdef SYSV
- Xstatic struct termio C_tp, O_tp;
- X#else
- Xstatic struct sgttyb C_tp;
- Xstatic unsigned short O_lflag;
- X#endif
- X
- Xstatic unsigned S_flag=0;
- Xstatic int R_ignore=0; /* up/down counter of reset calls to ignore */
- X
- X#define IO_GOT 1 /* have polled for original terminal mode */
- X#define IO_RAW 2 /* in RAW (CBREAK actually) mode */
- X
- X/*
- X tty_set handles ioctl calls. SAVEMODE, RESTORE are used around
- X system calls and interrupts to assure cooked mode, and restore
- X raw if raw on SAVEMODE. The pair results in no calls to ioctl
- X if we are cooked already when SAVEMODE is called, and may be nested,
- X provided we desire no "restore" of cooked mode after restoring raw.
- X
- X When we get the original terminal mode, we also save erase and kill.
- X
- X sig_set makes an ioctl call to get process group leader. Otherwise
- X ioctl calls should come through here.
- X*/
- Xtty_set(cmd)
- Xint cmd;
- X{
- X int rc;
- X unsigned mask;
- X
- X switch (cmd)
- X {
- X case BACKSTOP:
- X#ifdef JOBCONTROL
- X if ((rc = ioctl(1,TIOCLGET,&mask)) != 0)
- X break;
- X mask |= LTOSTOP;
- X rc = ioctl(1,TIOCLSET,&mask);
- X#else
- X rc = 0;
- X#endif
- X break;
- X case RAWMODE:
- X if ((S_flag & IO_RAW) != 0)
- X {
- X rc = 0;
- X break;
- X }
- X if ((S_flag & IO_GOT) == 0)
- X {
- X /* Save original modes, get erase / kill */
- X#ifdef SYSV
- X rc = ioctl(0,TCGETA,&C_tp);
- X O_tp = C_tp;
- X Erasekey = C_tp.c_cc[VERASE];
- X Killkey = C_tp.c_cc[VKILL];
- X#else
- X rc = ioctl(0,TIOCGETP,&C_tp);
- X O_lflag = C_tp.sg_flags;
- X Erasekey = C_tp.sg_erase;
- X Killkey = C_tp.sg_kill;
- X#endif
- X }
- X#ifdef SYSV
- X C_tp.c_lflag &= ~(ECHO | ICANON);
- X C_tp.c_cc[VMIN] = 1;
- X rc = ioctl(0,TCSETAW,&C_tp);
- X#else
- X C_tp.sg_flags |= CBREAK;
- X C_tp.sg_flags &= ~ECHO;
- X rc = ioctl(0,TIOCSETP,&C_tp);
- X#endif
- X S_flag = IO_GOT|IO_RAW;
- X break;
- X case COOKED:
- X if ((S_flag & IO_RAW) != 0)
- X {
- X#ifdef SYSV
- X C_tp = O_tp;
- X rc = ioctl(0,TCSETAW,&C_tp);
- X#else
- X C_tp.sg_flags = O_lflag;
- X rc = ioctl(0,TIOCSETP,&C_tp);
- X#endif
- X S_flag &= ~IO_RAW;
- X }
- X else
- X rc = 0;
- X break;
- X case SAVEMODE:
- X if ((S_flag & IO_RAW) != 0)
- X {
- X tty_set(COOKED);
- X R_ignore = 0;
- X }
- X else
- X ++R_ignore;
- X rc = 0;
- X break;
- X case RESTORE:
- X if (R_ignore <= 0)
- X {
- X tty_set(RAWMODE);
- X }
- X else
- X --R_ignore;
- X rc = 0;
- X break;
- X default:
- X rc = -1;
- X }
- X if (rc < 0)
- X printex ("ioctl failure, tty_set: %d",cmd);
- X}
- @//E*O*F tty_set.c//
- if test 2552 -ne "`wc -c <'tty_set.c'`"; then
- echo shar: error transmitting "'tty_set.c'" '(should have been 2552 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'tune.h'" '(2613 characters)'
- if test -f 'tune.h' ; then
- echo shar: will not over-write existing file "'tune.h'"
- else
- sed 's/^X//' >tune.h <<'@//E*O*F tune.h//'
- X/*
- X** vn news reader.
- X**
- X** tune.h - system tuning parameters
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X/*
- X** buffer size needed for tmpnam()
- X*/
- X#ifndef L_tmpnam
- X#define L_tmpnam 48
- X#endif
- X
- X/*
- X** hash table size. linked list type of table which can expand to
- X** arbitrary density, including densities > 100%. Number of entries
- X** will be number of newsgroups in active list. This should be a prime
- X** number ("long division" of string modulo table size hash function).
- X*/
- X#define HASHSIZE 809
- X
- X/*
- X** maximum number of columns on terminal. If made smaller, there
- X** will be a savings in the size of the temporary file used
- X** for holding displays, at the penalty of not being able to use
- X** the entire screen width on terminals actually possessing more
- X** columns than this. A block roughly on the order of this value
- X** times the number of lines the terminal has is maintained per page in
- X** the temp file, and read / written as displays are interacted
- X** with. MIN_C put here because MAX_C > MIN_C. MIN_C is the minumum
- X** number of columns for which a "reasonable" display can be produced.
- X** before making it smaller, look at all uses of C_allow and variable
- X** to see that a setting that small won't screw up array bounds.
- X*/
- X#define MAX_C 132
- X#define MIN_C 36
- X
- X/*
- X** large size for general purpose local buffers. only used in automatic
- X** variable declarations. Used with fgets for buffer size when reading
- X** file records, to hold pathnames, commands, etc. Reduce if you blow
- X** out stack storage. If reduced too far, will eventually show up
- X** as syntax errors on reading .newsrc's and the active list, and
- X** scrozzled article information arising from truncated header lines.
- X** The reply path line will probably be the first thing to cause trouble.
- X** Look through the reader to find the worst case chain of declarations
- X** (on the order of 12 or so is probably the max).
- X*/
- X#define RECLEN 1200
- X
- X/*
- X** to protect against reading entire articles to find non-existent header
- X** lines if an article should be hosed, only a limited number of records
- X** are searched. Should be big enough to get down to the last header
- X** entry on legitimate articles.
- X*/
- X#define HDR_LINES 24 /* records of article to search for header line */
- X
- X/* these determine some static array sizes */
- X#define OPTLINES 60 /* maximum number of option lines in .newsrc */
- X#define NUMFILTER 24 /* max number of filters on articles */
- X
- X/* block sizes for allocation routines */
- X#define STRBLKSIZE 1800 /* string storage allocation block */
- X#define NDBLKSIZE 50 /* NODE structures to allocate at a time */
- @//E*O*F tune.h//
- if test 2613 -ne "`wc -c <'tune.h'`"; then
- echo shar: error transmitting "'tune.h'" '(should have been 2613 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'userlist.c'" '(1923 characters)'
- if test -f 'userlist.c' ; then
- echo shar: will not over-write existing file "'userlist.c'"
- else
- sed 's/^X//' >userlist.c <<'@//E*O*F userlist.c//'
- X/*
- X** vn news reader.
- X**
- X** userlist.c - generate user's list of articles
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include "vn.h"
- X
- Xextern PAGE Page;
- X
- X/*
- X generate user list of articles - either article numbers
- X are input directly (numeric list), or input is a search
- X string - invoke regular expression library and examine titles
- X search string "*" reserved for marked articles. Strings may
- X be prefixed with '!' for negation.
- X*/
- Xuserlist (list)
- Xchar *list;
- X{
- X int i,j,anum[RECLEN/2],acount;
- X char neg, *s, sbuf[MAX_C+1], *reg, *regex(), *regcmp(), *index(), *strtok();
- X
- X user_str (sbuf,"Articles or title search string : ",1);
- X if (sbuf[0] == '!')
- X {
- X neg = '!';
- X s = sbuf+1;
- X }
- X else
- X {
- X neg = '\0';
- X s = sbuf;
- X }
- X for (i=0; s[i] != '\0'; ++i)
- X {
- X if (index(LIST_SEP,s[i]) == NULL)
- X {
- X if (s[i] < '0' || s[i] > '9')
- X break;
- X }
- X }
- X acount = 0;
- X
- X if (s[i] == '\0')
- X {
- X for (s = strtok(s,LIST_SEP); s != NULL; s = strtok(NULL,LIST_SEP))
- X {
- X anum[acount] = atoi(s);
- X ++acount;
- X }
- X }
- X else
- X {
- X if (s[0] == ART_MARK)
- X {
- X for (i=0; i < Page.h.artnum; ++i)
- X {
- X if (Page.b[i].art_mark == ART_MARK)
- X {
- X anum[acount] = Page.b[i].art_id;
- X ++acount;
- X }
- X }
- X }
- X else
- X {
- X reg = regcmp(s,(char *) 0);
- X if (reg != NULL)
- X {
- X for (i=0; i < Page.h.artnum; ++i)
- X {
- X if (regex(reg,Page.b[i].art_t) != NULL)
- X {
- X anum[acount] = Page.b[i].art_id;
- X ++acount;
- X }
- X }
- X regfree (reg);
- X }
- X else
- X preinfo ("bad regular expression syntax");
- X }
- X }
- X
- X /* algorithm is inefficient, but we're only handling a few numbers */
- X *list = '\0';
- X for (i=0; i < Page.h.artnum; ++i)
- X {
- X for (j=0; j < acount && anum[j] != Page.b[i].art_id; ++j)
- X ;
- X if (neg == '!')
- X {
- X if (j < acount)
- X continue;
- X }
- X else
- X {
- X if (j >= acount)
- X continue;
- X }
- X sprintf (list,"%d ",Page.b[i].art_id);
- X list += strlen(list);
- X }
- X}
- @//E*O*F userlist.c//
- if test 1923 -ne "`wc -c <'userlist.c'`"; then
- echo shar: error transmitting "'userlist.c'" '(should have been 1923 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'vn.h'" '(4278 characters)'
- if test -f 'vn.h' ; then
- echo shar: will not over-write existing file "'vn.h'"
- else
- sed 's/^X//' >vn.h <<'@//E*O*F vn.h//'
- X/*
- X** vn news reader.
- X**
- X** vn.h - general parameters
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include "tune.h"
- X
- X#define TRUE 1
- X#define FALSE 0
- X
- X#ifdef OLDRC
- X#define NARGOPT "lprxfuMs"
- X#else
- X#define NARGOPT "lprxfuMsi"
- X#endif
- X
- X#define FIL_AUTHOR 'w'
- X#define FIL_TITLE 't'
- X
- X/*
- X newsrc states
- X*/
- X#define NEWS_ON ':'
- X#define NEWS_OFF '!'
- X
- X/* bit flags for state of newsgroup */
- X#define FLG_SCAN 1
- X#define FLG_SUB 2
- X#define FLG_PAGE 4
- X#define FLG_WRIT 8
- X#define FLG_SPEC 16
- X
- X#define LIST_SEP " ,"
- X#define ED_MARK '>'
- X#define ART_MARK '*'
- X#define ART_WRITTEN '_'
- X#define ART_UNWRITTEN ' '
- X
- X#define FPFIX "Re: "
- X#define FPFLEN 4
- X
- X#define ANFORM ":%s - %c for help:\n"
- X#define ANFLINES 1
- X#define NOFORM "can't open article %s\n"
- X#define NEWGFORM "groups not mentioned in %s:\n"
- X#define SAVFORM "save file (%s) ? "
- X#define UDKFORM "undefined key - %c for help"
- X#define HELPFORM "%c for help"
- X
- X/*
- X page display format and dependent parameters
- X*/
- X#define HFORMAT "\n%s (page %d of %d):"
- X#define DHFORMAT "\n%s (DIGEST EXTRACTION):"
- X#define TFORMAT "%s ~ %s %s"
- X#define AFORMAT "\n%c%c%d) " /* begin with newline - see show routine */
- X#define CFORMAT "page %d of %d (%d shown), newsgroup %d of %d"
- X#define RECBIAS 2 /* lines before articles - depends on HFORMAT */
- X#define AFLEN 5 /* min. char. in article id - depends on AFORMAT */
- X#define WRCOL 1 /* column of written mark. depends on AFORMAT */
- X#define INFOLINE 0 /* HFORMAT TFORMAT leaves for use */
- X
- X/*
- X command characters - don't use numerics or <ESC>
- X ALTSAVE is a hack to avoid having to use ctl-s - XON/XOFF.
- X Wanted to preserve "s" pneumonic and lower / control /cap
- X convention.
- X*/
- X#define DIGEST 'd'
- X#define UP 'k'
- X#define DOWN 'j'
- X#define FORWARD '\012'
- X#define BACK '\010'
- X#define READ 'r'
- X#define ALTREAD ' '
- X#define READALL 'R'
- X#define READSTRING '\022'
- X#define SAVE 's'
- X#define SAVEALL 'S'
- X#define SAVESTRING '\023'
- X#define ALTSAVE '\024'
- X#define PRINT 'p'
- X#define PRINTALL 'P'
- X#define PRINTSTRING '\020'
- X#define MARK 'x'
- X#define UNMARK 'X'
- X#define REDRAW '\014'
- X#define QUIT 'q'
- X#define SSTAT '#'
- X#define GRPLIST '%'
- X#define ORGGRP 'o'
- X#define ORGSTAT 'O'
- X#define UPDATE 'w'
- X#define UNSUBSCRIBE 'u'
- X#define UPALL 'W'
- X#define UPSEEN '\027'
- X#define UNESC '!'
- X#define NEWGROUP 'n'
- X#define HEADTOG 'h'
- X#define SETROT 'z'
- X#define HELP '?'
- X#define HELP_HEAD "[...] = effect of optional number preceding command\n\
- Xpipes are specified by filenames beginning with |\n\
- Xarticles specified as a list of numbers, title search string, or\n\
- X * to specify marked articles. ! may be used to negate any\n"
- X
- X#define HHLINES 5 /* lines (CRs + 1) contained in HELP_HEAD */
- X
- X/*
- X state flags for handling breaks / values for sig_set calls.
- X BRK_IN, BRK_SESS, BRK_READ and BRK_OUT are the states. All
- X but BRK_INIT are used as calls to sig_set. BRK_RFIN indicates
- X a return from BRK_READ to BRK_SESS (no jump location passed),
- X*/
- X#define BRK_INIT 0 /* initial value, indicating uncaught signals */
- X#define BRK_IN 1 /* in NEWSRC / article scanning phase */
- X#define BRK_SESS 2 /* in page interactive session */
- X#define BRK_READ 3 /* reading articles */
- X#define BRK_RFIN 4 /* finished reading, return to old mode */
- X#define BRK_OUT 5 /* NEWSRC updating phase */
- X
- X#define BRK_PR "really quit ? "
- X#define BRK_MSG "\nQUIT (signal %d)"
- X
- X/*
- X newsgroup structure (node of hash table)
- X next - hashtable link
- X nd_name - name of newsgroup (key to reach node by)
- X pnum - page number, initially used to establish Newsorder
- X pages - number of pages for news display
- X rdnum - articles read
- X orgrd - original articles read number
- X pgshwn - pages shown mask
- X pgrd - article number on highest conecutively shown page
- X art - articles in group
- X state - status
- X*/
- Xtypedef struct _node
- X{
- X struct _node *next;
- X char *nd_name;
- X int pnum,pages,art,rdnum,orgrd,pgrd;
- X unsigned long pgshwn;
- X unsigned state;
- X} NODE;
- X
- X/*
- X newsgroup information for page display
- X name - of group
- X group - pointer to table entry
- X artnum - number of articles
- X*/
- Xtypedef struct
- X{
- X char *name;
- X NODE *group;
- X int artnum;
- X} HEAD;
- X
- X/*
- X article information - id (spool) number, title string, mark, written.
- X*/
- Xtypedef struct
- X{
- X int art_id;
- X char art_mark;
- X char art_written;
- X char art_t[MAX_C-AFLEN];
- X} BODY;
- X
- Xtypedef struct
- X{
- X HEAD h;
- X BODY *b;
- X} PAGE;
- @//E*O*F vn.h//
- if test 4278 -ne "`wc -c <'vn.h'`"; then
- echo shar: error transmitting "'vn.h'" '(should have been 4278 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'vnglob.c'" '(1613 characters)'
- if test -f 'vnglob.c' ; then
- echo shar: will not over-write existing file "'vnglob.c'"
- else
- sed 's/^X//' >vnglob.c <<'@//E*O*F vnglob.c//'
- X/*
- X** vn news reader.
- X**
- X** vnglob.c - global variables - see string.c also
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include "config.h"
- X#include "vn.h"
- X#include "head.h"
- X
- X/*
- X global data structure
- X*/
- XNODE **Newsorder; /* .newsrc file order */
- X
- Xchar *Editor,*Ps1,*Mailer,*Printer,*Poster;
- X
- Xchar Erasekey, Killkey; /* user keys from stty */
- Xchar *Newsrc, *Orgdir; /* .newsrc file, and original pwd */
- Xchar *Onews; /* temp. file for backing up .newsrc */
- Xchar *Savefile = DEF_SAVE; /* file in which to save articles */
- Xchar *Savedir; /* default directory for saved articles */
- Xchar *Ccfile; /* author_copy file, stored /bin/mail fmt */
- X
- Xint Rot; /* rotation */
- Xint Headflag; /* header printing flag */
- Xint Digest; /* if non-zero, digest article */
- X
- Xchar *Ku, *Kd, *Kl, *Kr; /* Cursor movement capabilities */
- X
- X/* character translation arrays for commands */
- Xchar Cxitop[128], Cxitor[128], Cxrtoi[128], Cxptoi[128];
- X
- X/*
- X cur_page - current page displayed;
- X lrec - last record
- X l_allow - lines allowed for article display
- X c_allow - columns allowed
- X ncount = newsorder index
- X nfltr - number of filters
- X*/
- Xint Cur_page, Lrec, L_allow, C_allow, Ncount, Nfltr;
- X
- X/*
- X article filtration options.
- X*/
- Xchar *Wopt[NUMFILTER]; /* regular expressions for -w options */
- Xchar *Topt[NUMFILTER]; /* regular expressions for -t options */
- Xchar *Negwopt[NUMFILTER]; /* regular expressions for negated -w options */
- Xchar *Negtopt[NUMFILTER]; /* regular expressions for negated -t options */
- X
- Xint Nwopt, Ntopt, Nnwopt, Nntopt;
- X
- Xint Nounsub, Listfirst;
- X/*
- X current page
- X*/
- XPAGE Page;
- @//E*O*F vnglob.c//
- if test 1613 -ne "`wc -c <'vnglob.c'`"; then
- echo shar: error transmitting "'vnglob.c'" '(should have been 1613 characters)'
- fi
- fi # end of overwriting check
- echo shar: "End of archive 2 (of 3)."
- cp /dev/null ark2isdone
- DONE=true
- for I in 1 2 3; do
- if test -! f ark${I}isdone; then
- echo "You still need to run archive ${I}."
- DONE=false
- fi
- done
- case $DONE in
- true)
- echo "You have run all 3 archives."
- echo 'Now read the README'
- ;;
- esac
- ## End of shell archive.
- exit 0
-